/**	
 * タイトル：	文件上传类
 * 説明：    	
 *			
 * 会社名：	紹興日創軟件有限公司
 * 変更履歴：	2014/08/14 NIS 何
 *			新規作成
 *
 */
package com.nissoft.framework.web.upload;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadBase;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

import com.nissoft.framework.exception.FileUploadException;
import com.nissoft.framework.util.ClassUtil;
import com.nissoft.framework.util.FileUtil;
import com.nissoft.framework.util.StringUtil;

/**
 * @author NIS 何
 * @version 1.0
 */
public class CommonFileUploader implements FileUploader {

	private final DiskFileItemFactory fileItemFactory;

	private final ServletFileUpload fileUpload;

	private String distDirectory;

	private List<String> extensions;

	public CommonFileUploader() {
		this.fileItemFactory = new DiskFileItemFactory(1024 * 10, new File(
				System.getProperty("java.io.tmpdir")));
		this.fileUpload = new ServletFileUpload(fileItemFactory);
	}

	/**
	 * 上传文件
	 * 
	 * @param request
	 *            HTTP请求
	 * @return 表单名-相对路径
	 * @throws FileUploadException
	 */
	public Map<String, String> upload(HttpServletRequest request)
			throws FileUploadException {
		return upload(request, new UploadCallback());
	}

	/**
	 * 
	 * @param request
	 *            HTTP请求
	 * @param callback
	 *            上传回调
	 * @return 表单名-相对路径
	 * @throws FileUploadException
	 */
	public Map<String, String> upload(HttpServletRequest request,
			UploadCallback callback) throws FileUploadException {

		if (!ServletFileUpload.isMultipartContent(request)) {
			return new HashMap<String, String>();
		}
		List<FileItem> items = null;
		Map<String, String> map = new HashMap<>();
		try {
			// 解析请求
			items = fileUpload.parseRequest(request);
			for (FileItem item : items) {
				// 非普通表单对象&&大小不为0
				if (!item.isFormField()) {
					// 文件名为空
					if (StringUtil.isEmpty(item.getName())) {
						continue;
					}
					UploadFile uploadFile = new UploadFile(item);
					// 后缀名是否被允许
					if (!checkExtension(uploadFile.getFileName())) {
						String message = "allowed extensions is: "
								+ extensions
								+ ";the file's extension is: "
								+ FileUtil.getExtension(uploadFile
										.getFileName());
						// 后缀名不被允许异常
						throw new FileUploadException(
								FileUploadException.EXTENSION_NOT_ALLOW,
								message);
					}
					// 存储相对路径
					String location = callback.getRelativePath(uploadFile);
					uploadFile.setRelativePath(location);
					// 路径是空不上传
					if (StringUtil.isEmpty(location)) {
						continue;
					}
					// 存储绝对路径
					location = distDirectory + FileUtil.standrdPath(location);
					File distFile = new File(location);
					// 创建目录
					distFile.getParentFile().mkdirs();
					// 写入文件
					item.write(distFile);
					// LogUtil.debug("fieldName:" + item.getFieldName() + "\t"
					// + "path:" + uploadFile.getRelativePath());
					map.put(item.getFieldName(), uploadFile.getRelativePath());
					uploadFile.setAbsolutePath(location);
					// 成功后回调
					callback.successed(uploadFile);
				}
			}
			return map;
		} catch (FileUploadBase.SizeLimitExceededException ex) {
			// 上传大小限制异常
			throw new FileUploadException(FileUploadException.MAX_SIZE_EXCEED,
					ex.getMessage(), ex);
		} catch (Exception ex) {
			// 其他上传异常
			throw new FileUploadException(FileUploadException.SYSTEM_ERR,
					ex.getMessage(), ex);
		} finally {
			if (items != null) {
				for (FileItem item : items) {
					item.delete();
				}
			}
		}
	}

	/**
	 * 获取存储目录
	 */
	public String getDistDirectory() {
		return distDirectory;
	}

	/**
	 * 文件存储目录
	 * 
	 * @param distDirectory
	 */
	public void setDistDirectory(String distDirectory) {
		this.distDirectory = ClassUtil.getPath(distDirectory);
	}

	/**
	 * 文件上传最大值
	 * 
	 * @param maxSize
	 *            大小(b)
	 */
	public void setMaxUploadSize(long maxSize) {
		this.fileUpload.setSizeMax(maxSize);
	}

	/**
	 * 允许的后缀名
	 * 
	 */
	public List<String> getExtensions() {
		return extensions;
	}

	/**
	 * 允许的后缀名
	 * 
	 * @param extensions
	 */
	public void setExtensions(List<String> extensions) {
		this.extensions = new ArrayList<String>();
		for (String ext : extensions) {
			this.extensions.add(ext.trim());
		}
	}

	/**
	 * 判断文件后缀名是否被允许
	 * 
	 */
	private boolean checkExtension(String fileName) {

		if (extensions == null || extensions.size() == 0) {
			return true;
		}
		String fileExt = FileUtil.getExtension(fileName);
		for (String ext : extensions) {
			if (fileExt.equalsIgnoreCase(ext)) {
				return true;
			}
		}
		return false;
	}
}
